#ifndef LINEBB_HPP
#define LINEBB_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include "BoundingVolume.hpp"

#include <SmegTools/Config.h>
#include <SmegTools/Debug/DebugNew.hpp>

namespace smeg {
    namespace math {

////////////////////////////////////////////////////////////
/// Axis Aligned Bounding Volume
////////////////////////////////////////////////////////////
class Line : public BoundingVolume
{
public:
    ////////////////////////////////////////////////////////////
    /// Default Constructor    ///
    ////////////////////////////////////////////////////////////
                        Line(   const sf::Vector2f& _Extent1 = sf::Vector2f(), 
                                const sf::Vector2f& _Extent2 = sf::Vector2f() );
    ////////////////////////////////////////////////////////////
    /// Copy Constructor
    ///
    /// \param _Copy : Copy of the Line
    ///
    ////////////////////////////////////////////////////////////
                        Line( const Line& _Copy );
    ////////////////////////////////////////////////////////////
    /// Destructor
    ///
    ////////////////////////////////////////////////////////////
    virtual             ~Line();

    DECLARE_CLONE_FUNC( Line, BoundingVolume )
    
    ////////////////////////////////////////////////////////////
    /// Setup the Bounding Volume
    ///
    /// \param _Extent1 : First point of the line
    /// \param _Extent2 : Second point of the line
    ///
    ////////////////////////////////////////////////////////////
    virtual void        Setup( const sf::Vector2f& _Extent1, const sf::Vector2f& _Extent2 );
    
    ////////////////////////////////////////////////////////////
    /// Does the Bounding Volume overlaps with a Bounding Volume
    ///
    /// \param _Other : Other Volume to test
    ///
    /// \return Whether the _Other Bounding Volume overlaps with this Bounding Volume
    ///
    ////////////////////////////////////////////////////////////
    virtual bool        Overlaps( const BoundingBox& _Other ) const;
    virtual bool        Overlaps( const Circle& _Other ) const;
    virtual bool        Overlaps( const Line& _Other ) const;    
    bool                Overlaps( const sf::Vector2f& _Extent1, const sf::Vector2f& _Extent2 ) const;

    bool                Intersects( const Line& _Other, sf::Vector2f& _IntersectionPoint ) const;
    bool                Intersects( const sf::Vector2f& _Extent1, const sf::Vector2f& _Extent2, sf::Vector2f& _IntersectionPoint ) const;
    
    ////////////////////////////////////////////////////////////
    /// Does the Bounding Volume contains a Bounding Volume
    ///
    /// \param _Other : Other Volume to test
    ///
    /// \return Whether this contains the _Other Bounding Volume
    ///
    ////////////////////////////////////////////////////////////
    virtual bool        Contains( const BoundingBox& _Other ) const     { return false; }
    virtual bool        Contains( const Line& _Other ) const            { return false; }
    virtual bool        Contains( const Circle& _Other ) const          { return false; }

    ////////////////////////////////////////////////////////////
    /// Does the Bounding Volume contains a point
    ///
    /// \param _Point : Point to test
    ///
    /// \return Whether this contains the point
    ///
    ////////////////////////////////////////////////////////////
    virtual bool        Contains( const sf::Vector2f& _Point ) const;

    /*********************** Accessors ************************/
    const sf::Vector2f* GetExtents() const;

    virtual void        SetCenter( float _fX, float _fY );
    virtual void        MoveCenter( float _fX, float _fY );

    virtual float       GetPseudoRadius() const;

protected:
    ////////////////////////////////////////////////////////////
    /// Compute the center and the component of the line
    ////////////////////////////////////////////////////////////
    void                ComputeLine();

    /******************* Protected members ********************/
    sf::Vector2f        m_Extents[2];

#ifdef _DEBUG
public:
    virtual void        DebugRender( sf::RenderWindow* _pRenderWindow, const sf::Color& _Color = sf::Color::White, bool _bFull = false ) const;
#endif // _DEBUG
};

/************************** Inline ************************/
inline const sf::Vector2f* Line::GetExtents() const {
    return m_Extents;
}

    } // namespace math
} // namespace smeg

#include <SmegTools/Debug/DebugNewOff.hpp>

#endif // LINEBB_HPP
